package com.mvc.common;

import com.mvc.common.tools.AssertFuse;
import lombok.Data;

import java.io.Serializable;

/**
 * 服务间返回协议
 * @author JayEinstein
 */
@Data
public class Res<T> implements Serializable {

    /**
     * 编码
     */
    private final String code;

    private String msg;

    private T data;

    private Res() {
        this(ResultCode.BUSINESS_SUCCESS);
    }

    private Res(StatusCode statusCode) {
        this.code = statusCode.getCode();
        this.msg = statusCode.getMsg();
    }

    /**
     * 当前状态是否成功，"0" 和 "1"，ok 和 fail
     * @return 成功
     */
    public boolean isSuccess() {
        return ResultCode.isSuccess(code);
    }

    /**
     * 请求处理成功
     * @param <E>
     * @return
     */
    public static <E> Res<E> ok() {
        return new Res<>();
    }

    /**
     * 请求成功
     * @param businessRes 业务处理状态
     * @return
     */
    public static Res<Boolean> success(boolean businessRes) {
        if (businessRes) {
            return ok(true);
        }

        // 请求成功，但是业务处理失败
        Res<Boolean> failRes = new Res<>(ResultCode.BUSINESS_FAILURE);
        failRes.setData(false);
        return failRes;
    }

    /**
     * 系统出现异常
     * @param <E>
     * @return
     */
    public static <E> Res<E> error() {
        return new Res<>(ResultCode.ERROR);
    }

    public static <E> Res<E> error(Exception e) {
        Res<E> res = new Res<>(ResultCode.ERROR);
        res.setMsg(e.getMessage());
        return res;
    }

    /**
     * 调用第三方出现异常
     * @param <E>
     * @return
     */
    public static <E> Res<E> timeout() {
        return new Res<>(ResultCode.TIMEOUT);
    }

    public static <E> Res<E> ok(E e) {
        Res<E> res = new Res<>();
        res.setData(e);
        return res;
    }

    public static <E> Res<E> ok(E e, String msg) {
        Res<E> res = new Res<>();
        res.setData(e);
        res.setMsg(msg);
        return res;
    }

    public static <E> Res<E> okMsg(String msg) {
        Res<E> res = new Res<>();
        res.setMsg(msg);
        return res;
    }

    public static <E> Res<E> timeoutMsg(String msg) {
        Res<E> res = new Res<>(ResultCode.TIMEOUT);
        res.setMsg(msg);
        return res;
    }

    public static <E> Res<E> of(StatusCode statusCode) {
        return new Res<>(statusCode);
    }

    public static <E> Res<E> of(StatusCode statusCode, E e) {
        Res<E> res = new Res<>(statusCode);
        res.setData(e);
        return res;
    }

    public static <E> Res<E> of(StatusCode statusCode, E e, String msg) {
        Res<E> res = new Res<>(statusCode);
        res.setData(e);
        res.setMsg(msg);
        return res;
    }

    public static <E> Res<E> ofMsg(StatusCode statusCode, String msg) {
        Res<E> res = new Res<>(statusCode);
        res.setMsg(msg);
        return res;
    }

    /**
     * 标准获取数据流程
     * @param res 响应容器
     * @param <E> 响应数据类型
     * @return 数据结果
     */
    public static <E> E getData(Res<E> res) {

        if (res.isSuccess()) {
            return res.getData();
        }

        // res 异常继承
        throw AssertFuse.of(res);

    }

}
